﻿using System;
using System.Threading;

namespace Skynet.CommonLibrary.ThreadQueue.Center
{
    /// <summary>
    /// 具体操作中心
    /// </summary>
    ///<remarks>
    /// 作者：         李志强
    /// 开发时间：  2011-04-18
    /// </remarks>
    public class OperationCenter : DceoratorCenter 
    {
        private readonly Func<object,Action,object> _operationAction;
        
        /// <summary>
        /// 队列操作中心
        /// </summary>
        /// <param name="action">需要执行的方法体。
        /// 参数说明：
        /// object：表示事先设置的参数（OperationData）
        /// Action：是否让线程处于等待状态（AutoResetEvent.set()）
        /// object：需要返回的对象，这个对象会被传递到下一个操作中（OperationData）</param>
        public OperationCenter(Func<object, Action, object> action)
        {
            _operationAction = action;
        }

        /// <summary>
        /// 数据操作处理(线程操作)
        /// </summary>
        protected internal override void DataProcess()
        {
            while (true)
            {
                object obj = null;
                if (_operationAction != null && this.IsWait == false)
                {
                    obj = _operationAction(this.OperationData, () => { 
                        this.IsWait = true; 
                    });
                }
                //引发下个操作继续
                base.Operation(obj);
            }
        }

        #region IComponent<string> 成员

        public override void Operation(object o)
        {
            OperationData = o;
            //如果该线程在等待状态则激活该线程
            if (this.IsWait)
            {
                this.ContinueExecution();
            }
            else
            {
                if (_threadCount <= ThreadMaxCount)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(obj =>
                    {
                        if (_operationAction != null)
                        {
                            _operationAction(this.OperationData, null);
                            Interlocked.Decrement(ref _threadCount);
                        }
                    }));
                    Interlocked.Increment(ref _threadCount);
                }
            }
        }
        #endregion
        private int _threadCount = 1;
        private int _threadMaxCount;
        /// <summary>
        /// 设置最大线程数，表示如果当前线程正处于忙的状态时 利用线程池 操作的最大数量
        /// 如果不设置则默认是单线程操作
        /// </summary>
        public int ThreadMaxCount
        {
            get { return _threadMaxCount; }
            set 
            {
                _threadMaxCount = value;
                ThreadPool.SetMinThreads(_threadMaxCount / 2, _threadMaxCount / 2);
                ThreadPool.SetMaxThreads(_threadMaxCount, _threadMaxCount);
            }
        }
    }

}
